/*
 *  config.c
 *
 *  Copyright (C) 2011  Peter Polacik <polacik.p@gmx.com>,
 *  			Martin Habovstiak <martin.habovstiak@gmail.com>
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

/* Program includes */
#include "alogd.h"

/* Library includes */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void clonestr(char **addr, char *str)
{
	if (*addr != NULL) free(*addr);
	if ((*addr = malloc(sizeof(char) * (strlen(str) + 1 ))) == NULL)
		errorize("clonestr - allocation", E_ALLOC);
	strcpy(*addr, str);
}

void store_opt(char *key, char *val, conf_t *ret)
{
	switch (key[0]) {
		case 'l':
			if (!strcmp(key, "logdir"))
				clonestr(&(ret->logdir), val);
			break;
		case 'b':
			if (!strcmp(key, "backlog"))
				sscanf(val, "%d", &(ret->backlog));
			break;
		case 's': 
			if (!strcmp(key, "socket"))
				clonestr(&(ret->sockpath), val);
			break;
	}
}

void parse_line(char *lp, conf_t *ret)
{
	int i;
	for (i = 0; 
		(lp[i] == ' ' || lp[i] == '\t') && lp[i] != 0 && lp[i] != '#';
		 ++i);
	if (lp[i] == 0 || lp[i] == '#') return;
	char *key = &lp[i];

	for (; lp[i] != 0 && lp[i] != ' '; ++i);
	if (!lp[i])
		errorize("parsing config - invalid file", 1);

	lp[i] = 0;
	char *value = &lp[i+1];
#ifdef DEBUG
		fprintf(stderr, "[DEBUG] parse_line:key='%s' value='%s'\n",
			key, value);
#endif
	store_opt(key, value, ret);
}

conf_t *parse(char *filename)
{
	conf_t *ret;
	FILE *f;
	char *lineptr = NULL;
	//char *line;
	//char *s;
	size_t n = 0;
	ssize_t len;

	ret = (conf_t *)malloc(sizeof(conf_t));
	if (ret == NULL)
		errorize("parsing config - allocation", E_ALLOC);
#ifdef DEBUG
	fprintf(stderr, "[DEBUG] parse:ret @ %p\n", ret);
#endif
	ret->logdir = NULL;
	ret->sockpath = NULL;
	ret->backlog = -1;
	f = fopen(filename, "r");
	if (f == NULL)
		errorize("parsing config - opening", E_OPEN);
#ifdef DEBUG
	fprintf(stderr, "[DEBUG] parse:f @ %p\n", f);
#endif
	while ((len = getline(&lineptr, &n, f)) != -1) {
#ifdef DEBUG
		fprintf(stderr, "[DEBUG] line: size=%d content=\'%s\'\n", 
			len, lineptr);
#endif
		if (lineptr[len - 1] == '\n')
			lineptr[len - 1] = '\0';
		parse_line(lineptr, ret);
		free(lineptr);
		lineptr = NULL;
	}
	fclose(f);
	if (ret->logdir == NULL) {
		ret->logdir = (char *)malloc(strlen(LOGDIR_DEFAULT) + 1);
		if (ret->logdir == NULL)
			errorize("parsing config - logdir alloc (d)", 
				 E_ALLOC);
		strcpy(ret->logdir, LOGDIR_DEFAULT);
	}
	if (ret->sockpath == NULL) {
		ret->sockpath = (char *)malloc(strlen(SOCKPATH_DEFAULT) + 1);
                if (ret->sockpath == NULL)
                        errorize("parsing config - sockpath alloc (d)",
				 E_ALLOC);
                strcpy(ret->sockpath, SOCKPATH_DEFAULT);
	}
	if (ret->backlog == -1)
		ret->backlog = BACKLOG_DEFAULT;
#ifdef DEBUG
	fprintf(stderr, "[DEBUG] parse:ret @ %p\n", ret);
	fprintf(stderr, "\t->logdir @ %p : \'%s\'\n", ret->logdir,
		ret->logdir);
	fprintf(stderr, "\t->sockpath @ %p : \'%s\'\n", ret->sockpath,
		ret->sockpath);
	fprintf(stderr, "\t->backlog=%d\n", ret->backlog);
#endif
	return ret;
}
